using System;



namespace Fine.Collections.Intf
{
    /// <summary>
    /// A list (read only).
    /// </summary>
    /// <typeparam name="T">type of an item.</typeparam>
    public interface RRandomList<out T> : RList<T>
    {

        /// <summary>
        /// Origin index (index of the first item).
        /// </summary>
        /// <remarks>
        /// Accessible even if the collection is empty.
        /// </remarks>
        /// <seealso cref="LastIndex"/>
        int FirstIndex { get; }


        /// <summary>
        /// Index of the last item.
        /// </summary>
        /// <remarks>
        /// If the collection is empty, it is a value that less than the <see cref="FirstIndex"/>.
        /// </remarks>
        /// <seealso cref="FirstIndex"/>
        int LastIndex { get; }


        /// <summary>
        /// Represents a quick indexed access to the specified item.
        /// </summary>
        /// <remarks>
        /// The given index must be in [ FirstIndex .. LastIndex ] exclusively.
        /// </remarks>
        /// <param name="index"></param>
        /// <exception cref="CollectionIsEmptyException">when the collection is empty.</exception>
        /// <exception cref="IndexOutOfBoundsException">when index is incorrect.</exception>
        /// <seealso cref="FirstIndex"/>
        /// <seealso cref="LastIndex"/>
        T this[int index] { get; }


        /// <summary>
        /// Looks for the first item that meets the given predicate.
        /// </summary>
        /// <param name="predicate">predicate for analyze items.</param>
        /// <returns>index of the found item; or <tt>int.MinValue</tt> if not found.</returns>
        /// <seealso cref="IndexOf(System.Predicate{T},int)"/>
        int IndexOf(Predicate<T> predicate);


        /// <summary>
        /// Looks for the first item that meets the given predicate.
        /// </summary>
        /// <param name="predicate">predicate for analyze items.</param>
        /// <param name="startFromIndex">index of the item to start search from;
        ///                              should be in bounds of <see cref="FirstIndex"/>..<see cref="LastIndex"/>.</param>
        /// <returns>index of the found item; or <tt>int.MinValue</tt> if not found.</returns>
        /// <seealso cref="IndexOf(System.Predicate{T})"/>
        int IndexOf(Predicate<T> predicate, int startFromIndex);

    }
}